﻿// -----------------------------------------------------------------------
// <copyright file="BookMapper.cs" company="EPAM Systems">
////Copyright (c) EPAM Systems, 2012. All rights reserved.
// </copyright>
// -----------------------------------------------------------------------

namespace MBOP.Website.Infrastructure.Mappers
{
	#region Usings

	using System.Collections.Generic;

	using MBOP.Core.DTO;
	using MBOP.Core.Entities.Common;
	using MBOP.Core.Entities.Library;
	using MBOP.Core.Interfaces.Services;
	using MBOP.Website.ViewModels.Common;
	using MBOP.Website.ViewModels.Library;

	#endregion

	/// <summary>
	/// Provides mapping for books.
	/// </summary>
	public class BookMapper
	{
		#region Private Fields

		/// <summary>
		/// Represents book service
		/// </summary>
		private IBookService _bookService;

		/// <summary>
		/// Represents person information service
		/// </summary>
		private IPersonInformationService _personInfoSerivce;

		/// <summary>
		/// Represents the image mapper.
		/// </summary>
		private ImageMapper _imageMapper;

		#endregion

		/// <summary>
		/// Initializes a new instance of the <see cref="BookMapper"/> class.
		/// </summary>
		/// <param name="bookService">The <see cref="IBookService"/> implementer</param>
		/// <param name="personInfoService">The <see cref="IPersonInformationService"/> implementer</param>
		public BookMapper(IBookService bookService, IPersonInformationService personInfoService)
		{
			this._bookService = bookService;
			this._personInfoSerivce = personInfoService;
			this._imageMapper=new ImageMapper();
		}

		/// <summary>
		/// Maps book view model to book.
		/// </summary>
		/// <param name="bookViewModel">The book view model.</param>
		/// <returns>The book</returns>
		public Book MapBook(BookViewModel bookViewModel)
		{
			Book book = null;

			if (bookViewModel != null)
			{
				book = new Book()
				{
					Authors = bookViewModel.Authors,
					ID = bookViewModel.ID.HasValue ? bookViewModel.ID.Value : 0,
					Description = bookViewModel.Description,
					EAN = bookViewModel.EAN,
					Title = bookViewModel.BookTitle,
					ImageID = bookViewModel.Image.ID,
					ISBN = bookViewModel.ISBN,
				};

				PersonInfo ownerInfo = this._personInfoSerivce.GetPersonInfo(bookViewModel.OwnerID, PersonFindingType.ID, false);

				if (ownerInfo != null)
				{
					book.OwnerID = ownerInfo.ID;
				}
				else
				{
					book.OwnerID = null;
				}
			}

			return book;
		}

		/// <summary>
		/// Maps books to book view model collections.
		/// </summary>
		/// <param name="books">Collection of the books.</param>
		/// <param name="historyList">The history list mode.</param>
		/// <param name="waitingList">The waiting list mode.</param>
		/// <param name="currentPersonIdentity">The current person identity.</param>
		/// <returns>Collection of the books view models.</returns>
		public IEnumerable<BookViewModel> MapBook(IEnumerable<Book> books, ListMode historyList, ListMode waitingList, string currentPersonIdentity)
		{
			IList<BookViewModel> booksViewModels = new List<BookViewModel>();

			foreach (var book in books)
			{
				booksViewModels.Add(this.MapBook(book, historyList, waitingList, currentPersonIdentity));
			}

			return booksViewModels;
		}

		/// <summary>
		/// Maps book to book view model.
		/// </summary>
		/// <param name="book">The book.</param>
		/// <param name="historyList">The history list mode.</param>
		/// <param name="waitingList">The waiting list mode.</param>
		/// <param name="currentPersonIdentity">The current person identity.</param>
		/// <returns>The book view model.</returns>
		public BookViewModel MapBook(Book book, ListMode historyList, ListMode waitingList, string currentPersonIdentity)
		{
			BookViewModel bookViewModel = null;

			if (book != null)
			{
				bookViewModel = new BookViewModel()
				{
					Authors = book.Authors,
					ID = book.ID,
					Description = book.Description,
					BookTitle = book.Title,
					EAN = book.EAN,
					ISBN = book.ISBN,
					Image = this._imageMapper.MapImage(book.Image)
				};


				PersonInfo currentPersonInfo = this._personInfoSerivce.GetPersonInfo(book.OwnerID, PersonFindingType.ID, false);

				if (currentPersonInfo != null)
				{
					bookViewModel.OwnerName = currentPersonInfo.CommonName;
				}

				if (!string.IsNullOrEmpty(bookViewModel.OwnerName))
				{
					bookViewModel.OwnerID = book.OwnerID;
				}

				bookViewModel.Details = this.MapBookDetails(book, historyList, waitingList, currentPersonIdentity);
			}

			return bookViewModel;
		}

		/// <summary>
		/// Maps book subscription to book subscription view model.
		/// </summary>
		/// <param name="subscription">The book subscription.</param>
		/// <returns>The book subscription view model.</returns>
		public BookSubscriptionViewModel MapBookSubscription(BookSubscription subscription)
		{
			BookSubscriptionViewModel bookSubscriptionViewModel = null;

			if (subscription != null)
			{
				PersonInfo personInfo = this._personInfoSerivce.GetPersonInfo(subscription.PersonID, PersonFindingType.ID, false);

				bookSubscriptionViewModel = new BookSubscriptionViewModel()
				{
					BookID = subscription.BookID,
					Date = subscription.Date,
					SubscriptionSet = subscription.SubscriptionSet,
					SubscriptionState = (SubscribeState)subscription.State,
					PersonCommonName = personInfo.CommonName,
					PersonID = subscription.PersonID,
				};
			}

			return bookSubscriptionViewModel;
		}

		/// <summary>
		/// Maps book subscription view model to book subscription.
		/// </summary>
		/// <param name="subscriptionViewModel">The book subscription view model.</param>
		/// <returns>The book subscription.</returns>
		public BookSubscription MapBookSubscription(BookSubscriptionViewModel subscriptionViewModel)
		{
			BookSubscription subscription = null;
			if (subscriptionViewModel != null)
			{
				subscription = new BookSubscription()
				{
					BookID = subscriptionViewModel.BookID,
					Date = subscriptionViewModel.Date,
					ID = 0,
					PersonID = subscriptionViewModel.PersonID,
					State = (int)subscriptionViewModel.SubscriptionState,
					SubscriptionSet = subscriptionViewModel.SubscriptionSet
				};
			}

			return subscription;
		}

		/// <summary>
		/// Maps book subscriptions collection to book subscriptions view model collection.
		/// </summary>
		/// <param name="subscriptions">The book subscriptions collection.</param>
		/// <returns>The book subscription view models collection.</returns>
		public IEnumerable<BookSubscriptionViewModel> MapBookSubscription(IEnumerable<BookSubscription> subscriptions)
		{
			IList<BookSubscriptionViewModel> bookSubscriptionViewModels = new List<BookSubscriptionViewModel>();

			foreach (var subscription in subscriptions)
			{
				bookSubscriptionViewModels.Add(this.MapBookSubscription(subscription));
			}

			return bookSubscriptionViewModels;
		}

		/// <summary>
		/// Maps book to book details.
		/// </summary>
		/// <param name="book">The book.</param>
		/// <param name="historyListMode">The history list mode.</param>
		/// <param name="waitingListMode">The waiting list mode.</param>
		/// <param name="currentPersonLogonName">The current person identity.</param>
		/// <returns>The book details view model.</returns>
		public BookDetailsViewModel MapBookDetails(Book book, ListMode historyListMode, ListMode waitingListMode, string currentPersonLogonName)
		{
			BookDetailsViewModel bookDetailsViewModel = null;

			string currentPersonID = this._personInfoSerivce.GetPersonInfo(currentPersonLogonName, PersonFindingType.LogonIdentity, false).ID;

			if (book != null)
			{
				bookDetailsViewModel = new BookDetailsViewModel()
				{
					Reader = this.MapBookSubscription(this._bookService.GetReader(book)),
					HistoryList = this.MapBookSubscription(this._bookService.GetHistoryList(book)),
					WaitingList = this.MapBookSubscription(this._bookService.GetWaitingList(book)),
					HistoryListMode = historyListMode,
					WaitingListMode = waitingListMode,
					IsInWaitingList = this._bookService.IsInWaitingList(book, currentPersonID),
					CanAddInWaitingList = this._bookService.CanAddInWaitingList(book, currentPersonID),
					AuthenticatedUserID = currentPersonID
				};
			}

			return bookDetailsViewModel;
		}
	}
}